// ==UserScript==
// @name          Nortel Click To Call
// @namespace     http://www.nortel.com
// @description	  Enable click to call on phone numbers
// @include       *
// ==/UserScript==

//************* Absolute path to trixie install location needs to be configured ************************//
var trixieInstallLocation = "C://Program Files//Bhelpuri//Trixie//Scripts//";

var phoneExp = /^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}|(^\w\d{3,9})$/
	
var tokenIntervalValue = 0;
var terminalIntervalValue = 0;
var addressIntervalValue = 0;

var ssoToken = "";
var terminalName = "";
var terminalType = "";
var addressType = "";
var sourceAddress = "";
var destinationAddress = "";

var callImage = trixieInstallLocation + "call.jpeg";

var soapHeader = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ses="http://www.nortel.com/soa/oi/cct/types/SessionService" xmlns:typ="http://www.nortel.com/soa/oi/cct/types"> <soapenv:Header/>';

// Replaces all instances of the given substring.
String.prototype.replaceAll = function( strTarget, strSubString) {
	var strText = this;
    var intIndexOfMatch = strText.indexOf( strTarget );
      
    while (intIndexOfMatch != -1){
        strText = strText.replace( strTarget, strSubString )
      	intIndexOfMatch = strText.indexOf( strTarget );
    }
    return( strText );
}

//Handles account and form views
var nobr = document.getElementsByTagName("nobr");
	for (var i = 0; i < nobr.length; ++i) {
        
		var node = nobr[i];
		var reg = new RegExp(phoneExp);
		var str = node.innerHTML;
		
		if(reg.test(str)) {
			var numberString = str.toString();
			var number = stripString(numberString);
			html = node.innerHTML;
			node.innerHTML = "<a onclick='initData(" + number + ");' style='text-decoration:underline;cursor:pointer;'> " + 
							html + 
							"</a><img style='margin-top:2px;margin-left:4px;' src='" + callImage + "' alt='Click link to call' />"; 
		}
	}

//Handles individual account input fields
var input = document.getElementsByTagName("input");

for (var i = 0; i < input.length; ++i) {
        
	var node = input[i];
	var reg = new RegExp(phoneExp);
      
    var nodeString = node.value;
	    
	if( nodeString.length != 0 ) {
				
		if(node.type == "text" && reg.test(nodeString)) {
			
			var imgId = document.getElementById("img"+nodeString);
			if(imgId == null) {
	
				var img = document.createElement("img");
				img.setAttribute("id", "img"+nodeString);
				img.setAttribute("src", callImage);
				img.style.cursor="pointer";
				node.parentNode.insertBefore(img, node);		
			}
		}
    }
}

function initData(destinationNumber) {
	destinationAddress = destinationNumber;
	if(isValidData()) {
		if(ssoToken == "") {
			tokenIntervalValue = window.setInterval ( "getToken()", 1000 );
			callCCTLogin();
		}	
	}
}

function getToken () {
	
	if(ssoToken == "") {
		//wait for ajax response
	} else {
  
		//Have SSO token now, call getTerminalData and wait for return of getTerminals
		if(terminalName == "" || terminalType == "") {
			terminalIntervalValue = window.setInterval ( "getTerminalData()", 1000 );
			getTerminals();
		}
		
		clearInterval(tokenIntervalValue);//Stop polling getToken
	}
}

function callCCTLogin() {

	GM_xmlhttpRequest({
	    method: 'POST',
		url: services,
	    headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept': 'application/atom+xml,application/xml,text/xml'},
		data: soapHeader + '<soapenv:Body> <ses:LogInToCCTServerRequest>    <ses:authenticationLevel>  <typ:username>'+username+'</typ:username> <typ:password>'+password+'</typ:password> <typ:domain>'+domain+'</typ:domain> </ses:authenticationLevel> </ses:LogInToCCTServerRequest> </soapenv:Body> </soapenv:Envelope>',
		onload: function(responseDetails) {      
			token = responseDetails.responseText;
			ssoToken = token.substring(token.indexOf('ssoToken>')+16, token.indexOf('</ns2:ssoToken>')-8);
		}
	});
}

function getTerminalData() {
	
	if(terminalName == "" || terminalType == "") {
		//wait for ajax response
	} else {
		clearInterval(terminalIntervalValue);
		
		//Terminal name and type are set, now get source address
		if(sourceAddress == "") {
			addressIntervalValue = window.setInterval ( "getAddressData()", 1000 );
			getAddresses();
		}
	}
}

function getTerminals() {
	
	GM_xmlhttpRequest({
	    method: 'POST',
		url: services,
	    headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept': 'application/atom+xml,application/xml,text/xml'},
		data: soapHeader + '<soapenv:Body> <ses:GetTerminalsRequest> <ses:ssoToken> <typ:token>'+ssoToken+'</typ:token> </ses:ssoToken> </ses:GetTerminalsRequest> </soapenv:Body> </soapenv:Envelope>',
		onload: function(responseDetails) {      
			terminalData = responseDetails.responseText;
			terminalName = terminalData.substring(terminalData.indexOf('terminalName>')+13, terminalData.indexOf('</terminalName>'));
			terminalType = terminalData.substring(terminalData.indexOf('terminalType>')+13, terminalData.indexOf('</terminalType>'));
		}
	});
}	

function getAddressData() {
	if(sourceAddress == "" || addressType == "") {
		//wait for ajax response
	} else {
		clearInterval(addressIntervalValue);
		
		//We have all data to create contact so...
		createContact();
	}
}


function getAddresses() {
	
	GM_xmlhttpRequest({
	    method: 'POST',
		url: services,
	    headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept': 'application/atom+xml,application/xml,text/xml'},
		data: soapHeader + '<soapenv:Body> <ses:GetAddressesRequest> <ses:ssoToken> <typ:token>'+ssoToken+'</typ:token> </ses:ssoToken> </ses:GetAddressesRequest> </soapenv:Body> </soapenv:Envelope>',
		onload: function(responseDetails) {      
			var addressData = responseDetails.responseText;
			sourceAddress = addressData.substring(addressData.indexOf('addressName>')+12, addressData.indexOf('</addressName>'));
			addressType = addressData.substring(addressData.indexOf('addressType>')+12, addressData.indexOf('</addressType>'));
		}
	});
}	

function createContact() {
	
	GM_xmlhttpRequest({
	    method: 'POST',
		url: services,
	    headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept': 'application/atom+xml,application/xml,text/xml'},
		data: soapHeader + '<soapenv:Body> <ses:CreateContactRequest> <ses:ssoToken> <typ:token>'+ssoToken+'</typ:token> </ses:ssoToken> <ses:terminal> <typ:terminalName>'+terminalName+'</typ:terminalName> <typ:terminalType>'+terminalType+'</typ:terminalType> </ses:terminal> <ses:srcAddress> <typ:addressName>'+sourceAddress+'</typ:addressName> <typ:addressType>'+addressType+'</typ:addressType> </ses:srcAddress> <ses:dstAddress> <typ:addressName>'+destinationAddress+'</typ:addressName> <typ:addressType>'+addressType+'</typ:addressType> </ses:dstAddress> </ses:CreateContactRequest> </soapenv:Body> </soapenv:Envelope>',
		onload: function(responseDetails) {      
			//externalId = responseDetails.responseText;
		}
	});
}

function stripString(numberString) {
	var str = numberString.replaceAll("-","").replaceAll("(","").replaceAll(")","").replaceAll(" ","");
	return str;
}

function isValidData() {
	
    var valid = true;
	var msg = "The following configuration items are missing:\r";
	
	username = getCookie("username");
	password = getCookie("password");
	domain = getCookie("domain");
	services = getCookie("services");
	
	if(username == "") {
		msg = msg + "  Username\r";
		valid = false;
	} 
	
	if(password == "") {
		msg = msg + "  Password\r";
		valid = false;
	}
	
	if(domain == "") {
		msg = msg + "  Domain\r";
		valid = false;
	}
	
	if(services == "") {
		msg = msg + "  Services URL\r";
		valid = false;
	}
	
	if(!valid) {
		alert(msg);
		return valid;
	}
	
	return valid;
}

/************************ CONFIGURATION SET UP *******************************************/

var username = "";
var password = "";
var domain = "";
var services = "";	
	
	var form = document.createElement("form");
    form.setAttribute("id", "data_form");
		
	createConfigDiv();
	hideConfigDiv(true);//hides in pop up forms
    loadExternalCSS();
	
	document.onkeyup = KeyCheck;       
	function KeyCheck() {
		var KeyID = event.keyCode;
		//bind to ` key
		if(KeyID == 223) {
			displayConfigDiv();
		}
	}
    
	//Create div to host configuration form.  Binded to "`" key.
	function createConfigDiv() {
		
		//is config div already created
		if( document.getElementById("config") ) return;
		
		var divTag = document.createElement("div");
		divTag.id = "config";
		var h4 = document.createElement("h4");
		var text = document.createTextNode("Click to Call Set up");
		h4.appendChild(text);
		divTag.appendChild(h4);
		
		createFormInputFields("Username", "username");
		createFormInputFields("Password", "password");
		createFormInputFields("Domain", "domain");
		createFormInputFields("Services URL", "services");
				
		var submit = document.createElement("input");
		submit.setAttribute("class", "submit_button");
		submit.setAttribute("type", "button");
		submit.setAttribute("value", "Submit");
		submit.setAttribute("onclick", setConfigData);
		
		form.appendChild(submit);
		
		divTag.appendChild(form);//Add form to div
		document.body.appendChild(divTag);//Add div to body
				
	}
	 
    function createFormInputFields(labelName, inputName) {
        var input = document.createElement("input");
        input.setAttribute("type", "text");
		input.setAttribute("name", inputName);
		input.setAttribute("value", getCookie(inputName));
		
        var label = document.createElement("label");
        var labelText = document.createTextNode(labelName);
        label.appendChild(labelText);
        
        form.appendChild(label);
	    form.appendChild(input);
    }
    
    function loadExternalCSS() {
		document.createStyleSheet(trixieInstallLocation + 'style.css');
    	document.getElementById("config").style.display = "none";
    }
	
	function hideConfigDiv(hide) {
		if(hide) {
			document.getElementById("config").style.display = "none";
		} else {
			document.getElementById("config").style.display = "block";
		}
	}
	
	function displayConfigDiv() {
        var divstyle = new String();
        divstyle = document.getElementById("config").style.display;

        if(divstyle.toLowerCase()=="block" || divstyle == "") {
        	document.getElementById("config").style.display = "none";
        } else {
            document.getElementById("config").style.display = "block";
        }
    }
	
	function setConfigData() {
		var form = document.getElementById("data_form");
		var inputs = form.getElementsByTagName("input");
		
		for(var i=0; i<inputs.length; i++) {
			if(inputs[i].name == "username") {
				username = inputs[i].value;
			} else if(inputs[i].name == "password") {
				password = inputs[i].value;
			} else if(inputs[i].name == "domain") {
				domain = inputs[i].value;
			} else if(inputs[i].name == "services") {
				services = inputs[i].value;
			} 
	    }
		setCookies();
		alert("Data has been set");
		displayConfigDiv();
	}
	
	function setCookies() {
	
		var exdate=new Date();
		exdate.setDate(exdate.getDate()+9999);
		document.cookie = "username=" + username + ";expires=" + exdate.toGMTString();
		document.cookie = "password=" + password + ";expires=" + exdate.toGMTString();
		document.cookie = "domain=" + domain + ";expires=" + exdate.toGMTString();
		document.cookie = "services=" + services + ";expires=" + exdate.toGMTString();
	}	
	
	function getCookie(c_name) {
		if (document.cookie.length > 0) {
			c_start=document.cookie.indexOf(c_name + "=");
			if (c_start!=-1) {
				c_start=c_start + c_name.length+1;
		
				c_end=document.cookie.indexOf(";",c_start);
				if (c_end==-1) c_end=document.cookie.length;
				return unescape(document.cookie.substring(c_start,c_end));
			}
		}
		return "";
	}
